package cn.kgc.util;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.CompressionCodecs;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * @author YC
 */
@Data
@Component
public class JwtUtil {

    /**
     * 访问token令牌密钥
     */
    @Value("${jwt.secret}")
    private String tokenSignKey;
    /**
     * 过期时间
     * Spring框架的@Value("${jwt.expiration}")注解可以从配置文件中读值
     */
    @Value("${jwt.expiration}")
    private long tokenExpiration;
    /**
     * 刷新token过期时间
     */
    @Value("${jwt.refreshTokenExpiration}")
    private long refreshTokenExpiration;

    /**
     * 生成token令牌
     *
     * @param userId 用户id
     */
    public String generateAccessToken(String userId) {
        return Jwts.builder()
                //设置签发时间
                .setIssuedAt(new Date())
                //设置过期时间
                .setExpiration(new Date(System.currentTimeMillis() + tokenExpiration * 1000))
                //携带数据
                .claim("userId", userId)
                //设置签名方式
                .signWith(SignatureAlgorithm.HS512, tokenSignKey)
                //对token进行压缩(减少传输)
                .compressWith(CompressionCodecs.GZIP)
                .compact();
    }

    /**
     * 生成刷新token令牌
     * 由于访问令牌有存活时间，设置长存活时间或者--使用刷新令牌方法--
     *
     * @param userId 用户id
     */
    public String generateRefreshToken(String userId) {
        return Jwts.builder()
                //设置签发时间
                .setIssuedAt(new Date())
                //设置过期时间
                .setExpiration(new Date(System.currentTimeMillis() + refreshTokenExpiration * 1000))
                //携带数据
                .claim("userId", userId)
                //设置签名方式
                .signWith(SignatureAlgorithm.HS512, tokenSignKey + "_REFRESH")
                //对token进行压缩(减少传输)
                .compressWith(CompressionCodecs.GZIP)
                .compact();
    }

    /**
     * 根据用户Id验证令牌（模拟令牌的验证，此项目只用用户Id验证）
     */
    public String getUserId(String token, boolean isRefresh) {
        String key = isRefresh ? tokenSignKey + "_REFRESH" : tokenSignKey;
        Claims claims = Jwts.parser().setSigningKey(key).parseClaimsJws(token).getBody();
        return (String) claims.get("userId");
    }

}